/**
 * 各种工具函数
 */
import _ from 'lodash';
import config from '../configs/config';

export function randomStr(num = 16) {
	const str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
	let randomstr = '';
	for (let i = 0; i < num; i++) {
		randomstr += str[_.random(0, 51)];
	}
	return randomstr;
}

export function getDeviceStatus(status) {
	switch (status) {
		case 1:
			return '在线';
		case 2:
			return '离线';
		case 3:
			return '使用中';
		case 4:
			return '空闲';
		case 5:
			return '禁用';
		case 6:
			return '故障';
		case 7:
			return '待机';
		case 8:
			return '正常';
		case 9:
			return '告警';
		default:
			return '未知';
	}
}

export function getOnlineStatus(status) {
	switch (status) {
		case 1:
			return '在线';
		case 2:
			return '离线';
		default:
			return '未知';
	}
}

export function getPayType(status) {
	status = Number(status);
	switch (status) {
		case 1:
			return '微信公众号';
		case 2:
			return '微信APP支付';
		case 3:
			return '支付宝支付';
		case 4:
			return '充值卡支付';
		default:
			return '未知';
	}
}

export function getAlarmStatus(status) {
	switch (status) {
		case 0:
			return '未修复';
		case 1:
			return '已修复';
		default:
			return '未知';
	}
}

export function formatSeconds(a) {
	if (typeof a === 'undefined') {
		return '0';
	}
	// 格式时间
	let hh = parseInt(a / 3600);
	let dd = 0;
	let h = 0;
	if (hh >= 24) {
		dd = parseInt(hh / 24);
		h = hh % 24;
	}

	if (hh < 10) hh = `0${hh}`;
	let mm = parseInt((a - hh * 3600) / 60);
	if (mm < 10) mm = `0${mm}`;
	let ss = parseInt((a - hh * 3600) % 60);
	if (ss < 10) ss = `0${ss}`;
	const length = `${h}时${mm}分${ss}秒`;
	if (a > 0) {
		if (dd > 0) {
			return `${dd}天${length}`;
		}
		return length;
	} else {
		return 'NaN';
	}
}

/**
 * 防重复请求，必须调用unfetching，或者超时之后，才可以调用第二次
 */
class FetchHelper {
	key = {};
	fetching(key, timeout = 10) {
		const res = this.key[key];
		this.key[key] = true;
		setTimeout(() => this.unfetching(key), timeout * 1000);
		return res;
	}

	unfetching(key) {
		this.key[key] = false;
	}
}

export const fetchHelper = new FetchHelper();


export function timeToDes(time) {
	time = parseFloat(time);
	if (!time || isNaN(time)) return [0, 0, 0];
	const des = [];
	const m = 60 * 1000;
	const h = 60 * m;
	const d = 24 * h;
	des.push(Math.floor(time / d));
	time = time % d;
	des.push(Math.floor(time / h));
	time = time % h;
	des.push(Math.floor(time / m));
	return des;
}

export function stringJoin(arr) {
	return arr.reduce((p, v) => `${p}${v || ''}`, '');
}

let count = 0; // 请求队列数量
const waittingQueue = [];

/**
 * 限制同时请求的数量
 * @param {*} fun 请求的方法，需要是返回一个promise的方法
 */
export function queueControl(fun) {
	return function (params) {
		if (count >= config.maxRequest) { // 最多同时发起max个请求
			return new Promise(res => {
				waittingQueue.push({ res, params, fun });
			});
		}
		count++;
		return fun(params).then(next);
	};
}

function next(res) {
	count--;
	if (count >= config.maxRequest || !waittingQueue.length) return res;
	const tem = waittingQueue.shift();
	tem.fun(tem.params).then(next).then(tem.res);
	return res;
}

/**
 * 控制请求参数，同一参数不会发送多次请求
 * @param {*} fun
 */
export function paramsControl(fun) {
	const paramsMap = new Map();
	return (params = {}) => {
		const key = JSON.stringify(params);
		let promise = paramsMap.get(key);
		if (!promise) {
			promise = fun(params).then(res => { // 请求返回则删除111
				paramsMap.delete(key);
				return res;
			});
			paramsMap.set(key, promise);
		}
		return promise;
	};
}

let listeners = [];
/**
 * 订阅store变更
 * @param {Function} listener
 */
export function subscribe(listener) {
	listeners.push(listener);
	return function () {
		listeners = listeners.filter(f => f !== listener);
	};
}

/**
 * 执行listeners，主要给app.js和login.js使用
 */
export function runListeners(state) {
	Promise.resolve().then(() => {
		listeners.forEach(fun => fun(state));
	});
}

/*
 * JSON数组去重
 * @param: [array] json Array
 * @param: [string] 唯一的key名，根据此键名进行去重
 */
export function uniqueArray(array, key) {
	const result = [array[0]];
	for (let i = 1; i < array.length; i++) {
		const item = array[i];
		let repeat = false;
		for (let j = 0; j < result.length; j++) {
			if (item[key] == result[j][key]) {
				repeat = true;
				break;
			}
		}
		if (!repeat) {
			result.push(item);
		}
	}
	return result;
}

export function wait(timeout = 1000) {
	return new Promise(res => setTimeout(res, timeout));
}

// 防抖动（debounce）的promise版，每次调用都会返回一个promise，适合用于antd的Form.create包装过之后的自定义异步校验项的防抖
export function promiseDebounce(fun, delay = 0) {
	let timer;
	let callback = [];
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fun.apply(this, args).then((...res) => {
				callback.forEach(o => o.res(...res));
				callback = [];
			}).catch((...err) => {
				callback.forEach(o => o.ret(...err));
				callback = [];
			});
		}, delay);
		return new Promise((res, ret) => {
			callback.push({ res, ret });
		});
  };
}

// 判断两个值是否相等，对于object，会浅判断属性值是否相等，可以传第三个参数，一个要比较的属性名数组
export function equal(val, other, keys) {
	if (_.isObject(val)) {
		const k = keys || Object.keys(val);
		const ok = keys || Object.keys(other);
		if (k.length !== ok.length) {
			return false;
		} else {
			return !k.some(i => val[i] !== other[i]);
		}
	} else return val == other;
}

export function getAlarmListQueryData(state, payload, namespace = 'alarmList') {
	const { filterData, pageSize, current } = state[namespace];
	const queryData = {};
	if (filterData.keyWord)queryData[filterData.key] = filterData.keyWord;
	if (filterData.dateRange && filterData.dateRange.length) {
		if (filterData.dateRange[0])queryData.startTime = filterData.dateRange[0].format('YYYY-MM-DD 00:00:00');
		if (filterData.dateRange[1])queryData.endTime = filterData.dateRange[1].format('YYYY-MM-DD 23:59:59');
	}

	return {
		...queryData,
		currentPage: current,
		...payload,
		pageSize: payload && payload.size ? payload.size : pageSize,
		productId: state.app.productId
	};
}
